package com.thghh.bcode.model;

import com.thghh.table.BeanColumn;
import com.thghh.table.CheckException;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Zhikang.Peng
 * @version 1.0
 * @email thghh@qq.com
 * @date 2020/12/8 10:46
 */
public class Property {

    @Getter(AccessLevel.NONE)
    @Setter(AccessLevel.NONE)
    protected Map<String, PropertyDescriptor> propertyMap;

    public Property() {
        propertyMap = new HashMap<>();
        analyze();
    }

    /**
     * 对当前类进行分析
     */
    public void analyze() {
        try {
            Class clazz = this.getClass();
            Field[] fields = clazz.getDeclaredFields();
            BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (Field field : fields) {
                // A comment of the specified type exists
                if (field.isAnnotationPresent(BeanColumn.class)) {
                    BeanColumn beanColumn = field.getAnnotation(BeanColumn.class);
                    // title name and column index
                    String name = beanColumn.name();
                    for (int i = 0; i < propertyDescriptors.length; i++) {
                        String propertyName = propertyDescriptors[i].getName();
                        if (field.getName().equalsIgnoreCase(propertyName)) {
                            propertyMap.put(name, propertyDescriptors[i]);
                        }
                    }
                }
            }
        } catch (Exception e) {
            throw new CheckException(e);
        }
    }

    /**
     * 对指定名称的字段设置值
     *
     * @param propertyName
     * @param value
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public void setValue(String propertyName, Object value) throws IllegalAccessException, InvocationTargetException {
        propertyMap.get(propertyName).getWriteMethod().invoke(this, value);
    }

    /**
     * 获取指定字段的值
     *
     * @param propertyName
     * @return
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     */
    public Object getValue(String propertyName) throws IllegalAccessException, InvocationTargetException {
        Object[] empty = null;
        return propertyMap.get(propertyName).getReadMethod().invoke(this, empty);
    }
}
